package garbage;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
import org.eclipse.jdt.internal.core.JavaElement;

public class TreesSelector extends ASTVisitor {
	
	private Map<Integer,List<ASTNode>> _nodeKindToNodes = new HashMap<Integer,List<ASTNode>>();
	
	private void putToMap(ASTNode arg0) {
		if (_nodeKindToNodes.containsKey(arg0.getNodeType())) {
			_nodeKindToNodes.get(arg0.getNodeType()).add(arg0);
		} else {
			List<ASTNode> listWithOneTree = new LinkedList<ASTNode>();
			listWithOneTree.add(arg0);
			_nodeKindToNodes.put(arg0.getNodeType(), listWithOneTree);
		}
	}
	
	public void clear() {
		_nodeKindToNodes.clear();
	}
	
	@Override
	public boolean visit(TypeDeclaration arg0) {
		putToMap(arg0);
		
		ITypeBinding resolvedTypeBinding = arg0.resolveBinding();// .getName().resolveBinding();
		System.out.println(resolvedTypeBinding.getBinaryName());
		
		return super.visit(arg0);
	}
	
	@Override
	public boolean visit(TypeDeclarationStatement node) {
		putToMap(node);
		System.out.println(node.toString());
		return super.visit(node);
	}
	
	@Override
	public boolean visit(CompilationUnit arg0) {
		putToMap(arg0);
		return super.visit(arg0);
	}
	

	@Override
	public boolean visit(MethodDeclaration arg0) {
		putToMap(arg0);
		int flags = arg0.getFlags();
		int modifiers = arg0.getModifiers();
		int extraDimensions = arg0.getExtraDimensions();
		
		if ((modifiers & Modifier.PRIVATE) > 0)
			System.out.println("PRIVATE");
		if ((modifiers & Modifier.PROTECTED)>0)
			System.out.println("PROTECTED");
		if ((modifiers & Modifier.PUBLIC)>0)
			System.out.println("PUBLIC");
		if ((modifiers & Modifier.STATIC)>0)
			System.out.println("STATIC");
		
		ASTNode parentClass = arg0.getParent();
		while (parentClass.getNodeType() != ASTNode.TYPE_DECLARATION)
			parentClass = parentClass.getParent();
		
		
		System.out.println("Parent class:"+((TypeDeclaration)arg0.getParent()).getName().getFullyQualifiedName());
		
		System.out.println("flags:"+flags+" "+
			"modifiers:"+modifiers+" "+
			"extraDimensions:"+extraDimensions+" ");
		return super.visit(arg0);
	}
	
	@Override
	public boolean visit(Modifier arg0) {
		putToMap(arg0);
		return super.visit(arg0);
	}
	
	@Override
	public boolean visit(MethodInvocation arg0) {
		putToMap(arg0);
		
		ITypeBinding resolvedTypeBinding = arg0.getExpression().resolveTypeBinding();
		System.out.println(resolvedTypeBinding.getBinaryName());
		
		return super.visit(arg0);
	}
	
	public Map<Integer,List<ASTNode>> getChildrenTreesMap() {
		return _nodeKindToNodes;
	}
}
